package com.fg.cloud.framework.redis.finals;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.SerializationUtils;

import com.fg.cloud.framework.redis.RedisManager;

import redis.clients.jedis.JedisPool;

public class ShiroMemcachedCache<K, V> implements Cache<K, V>  {

	private final static Logger LOG = LoggerFactory.getLogger(ShiroMemcachedCache.class);  
	
	/** 缓存Key前缀 */
	private String CACHE_PREFIX;
	
	static RedisManager redisManager;
	
	public ShiroMemcachedCache() {
		// TODO Auto-generated constructor stub
	}
	
	public ShiroMemcachedCache(String cacheName){  
        CACHE_PREFIX = cacheName+"-";  
    }  
	
	@Override  
    public V get(K key) throws CacheException {
        V value = (V) redisManager.get(keyToString(key));  
        if(LOG.isDebugEnabled()){  
            LOG.debug("get the entity json is " + key + " : " + value);  
        }  
        return value;  
    }  
  
    @Override  
    public V put(K key, V value) throws CacheException {  
        if(LOG.isDebugEnabled()){  
            LOG.debug("begin save the "+ key + " : " + value+" to memcache");  
        }  
        redisManager.set(keyToString(key), value.toString());  
        return value;  
    }  
  
    @Override  
    public V remove(K key) throws CacheException {  
        if(LOG.isDebugEnabled()){  
            LOG.debug("begin remove the "+key+" from memcache");  
        }  
        V value = get(key);  
        redisManager.del(keyToString(key));  
        return value;  
    }  
  
    @Override  
    public void clear() throws CacheException {  
        for(Iterator<K> keys =keys().iterator();keys.hasNext();){  
            K key = keys.next();  
            remove(key);  
        }  
    }  
  
    @Override  
    public int size() {  
        return keys().size();  
    }  
  
    @Override  
    public Set<K> keys() {  
    	String tempKey = null;
        Set<String> keys = new HashSet<String>();  
        for(byte[] key : redisManager.keys("*")) {
        	tempKey = SerializationUtils.deserialize(key).toString();
            if(StringUtils.startsWith(tempKey, CACHE_PREFIX)){  
                keys.add(tempKey);  
            }  
        }  
        return (Set<K>)keys ;  
    }  
  
    @Override  
    public Collection<V> values() {  
        List<V> values = new ArrayList<V>();  
        for(Iterator<K> keys =keys().iterator();keys.hasNext();){  
            K key = keys.next();  
            V value = getValue(key);  
            values.add(value);  
        }  
        return values;  
    }  
    
    /**
     * Description:自定义设置Key-Value，不带前缀
     * @param key
     * @param value
     * @return
     * @author around
     * @date 2017年9月21日下午7:41:09
     */
    private V setValue(K key, V value) {
    	redisManager.set(key.toString(), value.toString());
    	if(LOG.isDebugEnabled()){  
            LOG.debug("get the entity json is " + key + " : " + value);  
        }  
    	return value;
    }
    
    /**
     * Description:自定义获取Key，不带前缀
     * @param key
     * @return
     * @throws CacheException
     * @author around
     * @date 2017年9月21日下午7:40:50
     */
    private V getValue(K key) throws CacheException {  
        V value = (V) redisManager.get(key.toString());  
        if(LOG.isDebugEnabled()){  
            LOG.debug("get the entity json is " + key + " : " + value);  
        }  
        return value;  
    }  
      
    private String keyToString(K key){  
        String k = String.valueOf(key);  
        if(StringUtils.startsWith(k, CACHE_PREFIX)){  
            return k;  
        }  
        return CACHE_PREFIX+k;  
    }  

	public static RedisManager getRedisManager() {
		return redisManager;
	}

	public static void setRedisManager(RedisManager redisManager) {
		ShiroMemcachedCache.redisManager = redisManager;
	}

	private JedisPool getJedisPool() {
		return redisManager.getJedisPool();
	}

}
